package com.gitee.huanminabc.fastboot.orm.proxy;

import com.gitee.huanminabc.jcommon.exception.CommonException;
import com.gitee.huanminabc.jcommon.reflect.ClassUtil;
import com.gitee.huanminabc.jcommon.reflect.GenericUtil;
import com.gitee.huanminabc.jcommon.reflect.MethodUtil;
import com.gitee.huanminabc.jcommon.reflect.ReflectPath;
import com.gitee.huanminabc.fastboot.context.AppContext;
import com.gitee.huanminabc.fastboot.orm.base.BaseMapper;
import com.gitee.huanminabc.fastboot.orm.base.BaseMapperInterceptorHandle;
import com.gitee.huanminabc.fastboot.proxy.InterceptorHandle;
import com.gitee.huanminabc.fastboot.proxy.ProxyInterceptor;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * bytebuddy 第一次加载类很慢,大概300~400ms  后面就快了, 只需要几ms
 *
 * @Author: huanmin
 * @Date: 2025/4/4 20:57
 * @Version: 1.0
 * @Description: 文件作用详细描述....
 */
public class OrmByteBuddyProxy {
    //只能代理默认方法
    public static <T> T createProxyBaseMapperMethod() {
        Class<BaseMapper> baseMapperClass = BaseMapper.class;
        BaseMapperInterceptorHandle baseMapperInterceptorHandle = new BaseMapperInterceptorHandle();
        try {
            DynamicType.Unloaded make = new ByteBuddy()
                    .subclass(Object.class)
                    .implement(baseMapperClass) // 代理BaseMapper ,只能是默认方法不支持接口
                    .method(ElementMatchers.any())
                    .intercept(MethodDelegation.to(ProxyInterceptor.class)) // 统一拦截到 ProxyInterceptor
                    .make();
            Class<? extends T> loaded = make
                    .load(baseMapperClass.getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
                    .getLoaded();
            T t = ClassUtil.newInstance(loaded);


            Method[] allPublicOneselfMethods = MethodUtil.getAllPublicOneselfMethods(baseMapperClass);
            //注册方法的代理
            for (Method filteredMethod : allPublicOneselfMethods) {
                String methodParamAllPath = ReflectPath.getMethodParamAll(filteredMethod);
                AppContext.interceptorHandleMap.computeIfAbsent(methodParamAllPath, k -> new ArrayList<>()).add(baseMapperInterceptorHandle);
            }
            return t; // 使用无参构造函数实例化
        } catch (Exception e) {
            throw new CommonException(e);
        }
    }
}
